/*
 *  Copyright (C) 2009  Peter Kist & Jan Ripke
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef __gfx_interface_h
#define __gfx_interface_h 1

#include <string>
#include <vector>

#include <mediator/Request.h>
#include <mediator/Event.h>
#include <world/Types.h>
#include <world/Entity.h>

/** get window handle from gfx module. Returns a GfxRequestResultString */
#define Request_TYPE_GFX_WINDOW_HANDLE 1
#define Request_TYPE_GFX_MENU_COMMAND 2

/** types for MenuEvent */
#define MODULE_TYPE_GFX_MENU_COMMAND    1

/** types for EntityEvent */
#define MODULE_TYPE_GFX_ENTITY_COMMAND  2


namespace galaxy {
    namespace gfx {

        /** gfx Request result object that returns window info */
        class GfxRequestWinInfo: public mediator::RequestResult {
        public:
            std::string windowHandle; /**< the result string. the caller must know how to interpret it */
            unsigned int width /**< window width */, height; /**< window height */
            unsigned int depth;                             /**< color depth */
            int top /**< top of window */, left;            /**< left position of window */ 
        };

        /** gfx menu types */
        struct Menu {

            /** the command for menu events */
            typedef enum _command {
                GFX_MENU_SHOW = 1, /**< show the specified menu */
                GFX_MENU_HIDE = 2, /**< hide the specified menu */
            } Command;

            /** the name of the menu to show/hide */
            typedef std::string const Name;

            static Name c_MainMenu;
            static Name c_Settings;
            static Name c_Credits;
            static Name c_ServerSelect;

        };

        class MenuEvent : public mediator::Event {
        public:

            Menu::Name m_MenuName;

            MenuEvent(MenuEvent& event) : Event (event), m_MenuName(event.m_MenuName) {
            }
            MenuEvent(Menu::Command command, Menu::Name& menuName)
                : mediator::Event(mediator::CATEGORY_GFX, MODULE_TYPE_GFX_MENU_COMMAND,
                (int) command), m_MenuName (menuName) {
            }

            virtual Event * clone () { return new MenuEvent(*this); };
        };

        /** gfx menu types */
        struct Entity {
            typedef enum _command {
                GFX_ENTITY_POPULATE  = 1,   /** add entities to gfx module (to be displayed) */ 
                GFX_ENTITY_REMOVE    = 2,   /** remove entities to gfx module */
                GFX_ENTITY_UPDATE    = 3,   /** update entity's properties (e.g. position/direction) */
                GFX_ENTITY_UPGRADE   = 4,   /** upgrade entity's shape (e.g. billboard to mesh) */
                GFX_ENTITY_DOWNGRADE = 5,   /** downgrade entity's shape (e.g. mesh to billboard) */
            } Command;
        };

        /** Transport request to manipulate entities.
        * Note that the consumer (@see GalaxyConsumer) only handles POST_DELAYED events.
         */
        class EntityEvent : public mediator::Event {
        public:

            std::vector<world::Entity *> m_Entities;

            EntityEvent(EntityEvent& event) : Event (event), m_Entities(event.m_Entities) { };
            EntityEvent(Entity::Command command) 
                : mediator::Event(mediator::CATEGORY_GFX, MODULE_TYPE_GFX_ENTITY_COMMAND,
                (int) command)
            {
            }
            ~EntityEvent() {
            }
            virtual Event * clone () { return new EntityEvent(*this); };
        };

    } // namespace gfx
} // namespace galaxy



#endif // __gfx_interface_h
